import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:common/network/composer/t_request_callback.dart';
import 'package:common/common.dart';

abstract class TComposer {
  static Future<T> compose<T>(Future requestFuture, TRequestCallback<T> callback) async {


    Response response = await requestFuture.catchError((e) {
      if(callback.showNetworkErrorToast)
        _parseException(e);
     /* if (callback.showNetworkErrorToast) {
        Fluttertoast.showToast(
            toastLength: Toast.LENGTH_LONG,
            msg: callback.networkErrorToast,
            timeInSecForIosWeb: 3,
            backgroundColor: TColor.textError,
            textColor: Colors.white,
            gravity: callback.centerToast ? ToastGravity.CENTER : ToastGravity.BOTTOM);
      }*/
      callback.onFailedCode?.call(-1, callback.networkErrorToast);
      // callback.onComplete?.call(false);
      return null;
    });

    if (callback.isSuccessful(response)) {
      T t;
      try {
        if (callback.specifiedDataToParse == null) {
          t = callback.parse(response.data['data']);
        } else {
          t = callback.parse(callback.specifiedDataToParse(response));
        }
      } catch (e, s) {
        print("TDio: parsingError: ${response.request?.path},\n${e.toString()} $s");
        callback.onComplete?.call(false);
        return null;
      }
      callback.onComplete?.call(true);
      callback.onSuccess?.call(t);
      return t;
    } else {
      if (callback.onFailedCode != null) {
       // int code = response.data["code"] ?? -2;

        int code = -2;
        String message;
        if(response?.data != null){
          code = response.data["code"] ?? -2;
          message = response.data["msg"];
          if(message == null){
            message = response.data["message"];
          }
        }
        callback.onFailedCode.call(code, message);
      }else{

      }

      callback.onComplete?.call(false);
      String errorMessage;
      if (response?.data != null &&
          (TUtil.isNotEmptyString(response.data['msg']) || TUtil.isNotEmptyString(response.data['message']))) {
        errorMessage = TUtil.isNotEmptyString(response.data['msg']) ? response.data['msg'] : response.data['message'];
      }
      if (callback.showErrorMessageFromServer && TUtil.isNotEmptyString(errorMessage) && !UserBloc.isOffline) {
        Fluttertoast.showToast(
            msg: errorMessage,
            backgroundColor: TColor.textError,
            textColor: Colors.white,
            gravity: callback.centerToast ? ToastGravity.CENTER : ToastGravity.BOTTOM);
      }
      return null;
    }
  }

  static void _parseException(Exception error) {
    if (error is DioError) {
      switch (error.type) {
        case DioErrorType.CONNECT_TIMEOUT:
        case DioErrorType.RECEIVE_TIMEOUT:
        case DioErrorType.SEND_TIMEOUT:
        case DioErrorType.CANCEL:
        _toast('网络连接失败，请检查网络后重试');
        return;
        case DioErrorType.RESPONSE:
            int errCode = error.response?.statusCode;
            switch (errCode) {
              case 400:
                _toast('请求语法错误');
                return;
              case 401:
                _toast('没有权限');
                return;
              case 403:
                _toast('服务器拒绝执行');
                return;
              case 404:
                _toast('无法连接服务器');
                return;
              case 405:
                _toast('请求方法被禁止');
                return;
              case 500:
                _toast('服务器内部错误');
                return;
              case 502:
                _toast('无效的请求');
                return;
              case 503:
                _toast('服务器挂了');
                return;
              case 505:
                _toast('不支持HTTP协议请求');
                return;
              default:
                _toast('网络连接失败，请检查网络后重试');
                return;

            }
            return;
        default:
          _toast('网络连接失败，请检查网络后重试');
          return;

      }
    } else {
      _toast('网络连接失败，请检查网络后重试');
      return;
    }
  }


  static void _toast(title){
    Fluttertoast.showToast(
        msg: title,
        backgroundColor: TColor.textError,
        textColor: Colors.white,
        gravity: ToastGravity.BOTTOM);
  }

}
